// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: wsfuyibing <682805@qq.com>
// Date: 2025-04-02

package util

import (
	"gitee.com/go-libs/runtime/util/table"
	"gitee.com/go-libs/runtime/util/table/render"
	"reflect"
)

// ParseStructAlign
// 解析结构体对齐.
//
// 参数 a 接受 Struct, &Struct, []Struct, []*Struct 四种参数.
func ParseStructAlign(a any) (parsed table.Table) {
	// 1. 构建反射.
	v := reflect.ValueOf(a)
	t := v.Type()

	// 2. 类型转换.
	if v.Kind() == reflect.Slice {
		// 2.1 切片.
		if t = v.Type().Elem(); t.Kind() == reflect.Ptr {
			t = t.Elem()
		}
	} else if v.Kind() == reflect.Ptr {
		// 2.2 指针.
		t = v.Elem().Type()
	}

	// 3. 忽略类型.
	if t.Kind() != reflect.Struct {
		return
	}

	// 4. 开始解析.
	parsed = table.NewTable()
	parsed.SetTitle(t.PkgPath() + "." + t.Name())

	// 4.1 设置表头.
	head := table.NewHead()
	head.GetRow().Add(table.NewCell("Size"), table.NewCell("Field name"), table.NewCell("Type reference"))
	parsed.SetHead(head)

	// 4.2 计算表体.
	body := table.NewBody()
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		body.Add(table.NewRow().Add(
			table.NewCell(field.Type.Size()),
			table.NewCell(field.Name),
			table.NewCell(field.Type.String()),
		))
	}
	parsed.SetBody(body)
	return
}

// ParseStructAlignToTerminal
// 解析结构体对齐并在终端打印表格.
func ParseStructAlignToTerminal(v any, indents ...string) {
	if parsed := ParseStructAlign(v); parsed != nil {
		render.Terminal(parsed, indents...)
	}
}
